using System;
using Audio;
using PrimeTween;
using UnityEngine;
using World;

namespace Combat
{
    public class Bullet : MonoBehaviour
    {
        [SerializeField] private ParticleSystem hitEffect;
        [SerializeField] private ParticleSystem trailEffect;
        
        private SpriteRenderer _spriteRenderer;
        private TrailRenderer _trailRenderer;

        private BulletData _bulletData;
        private Vector3 _moveDirection;
        
        private Action<Bullet> _onDestroy;
        
        private Tween _destroyTween;


        private void Awake()
        {
            _spriteRenderer = GetComponent<SpriteRenderer>();
            _trailRenderer = GetComponentInChildren<TrailRenderer>();
        }

        private void Update()
        {
            Fly();
            CheckOutOfScreen();
        }

        private void OnTriggerEnter2D(Collider2D other)
        {
            // Not active
            if (!_spriteRenderer.enabled)
            {
                return;
            }
            
            if (other.TryGetComponent(out Health health) && !health.IsDead)
            {
                HitTarget(health);
            }
        }

        private void OnDestroy()
        {
            _destroyTween.Stop();
        }

        public void Setup(BulletData bulletData, Vector3 startPosition, Vector3 shootDirection, Action<Bullet> onDestroy)
        {
            _bulletData = bulletData;
            _spriteRenderer.color = bulletData.Color;
            
            _trailRenderer.colorGradient = bulletData.TrailColor;
            ParticleSystem.MainModule mainModule = trailEffect.main;
            mainModule.startColor = bulletData.TrailColor;
            if (bulletData.UseTrail)
            {
                _trailRenderer.gameObject.SetActive(true);
                trailEffect.gameObject.SetActive(false);
            }
            else
            {
                _trailRenderer.gameObject.SetActive(false);
                trailEffect.gameObject.SetActive(true);
            }
            
            transform.position = startPosition;
            _moveDirection = shootDirection;

            _spriteRenderer.enabled = true;
            enabled = true;
            
            _onDestroy = onDestroy;
        }

        private void HitTarget(Health health)
        {
            AudioPlayer.Instance.PlaySound(_bulletData.HitSound);
            
            health.TakeDamage(_bulletData.Damage, _moveDirection);
            OnHit();
            if (!_bulletData.Penetrate)
            {
                Disappear();
            }
        }

        private void OnHit()
        {
            hitEffect.Play();
        }

        private void Fly()
        {
            transform.position += _bulletData.MoveSpeed * Time.deltaTime * _moveDirection;
        }

        private void CheckOutOfScreen()
        {
            if (WorldInfo.Instance.IsOutOfBound(transform.position))
            {
                OnHit();
                Disappear();
            }
        }

        private void Disappear()
        {
            enabled = false;
            _spriteRenderer.enabled = false;
            _destroyTween = Tween.Delay(1f, DestroySelf);
        }

        private void DestroySelf()
        {
            _onDestroy?.Invoke(this);
        }
    }
}
